<?php

/**
 * Base functionalty for for user and client model classes
 * @package Nina
 * @author John Main <john@thedaddy.org>
 */
abstract class Nina_Model_User extends Nina_Model
{
	/**
	 * Generate a password reset code adn store it against the user
	 * @return string
	 */
	public function retrievePasswordCode() {
		$code = md5(Nina_Timestamp::now());

		$this->setPasswordCode($code);
		$this->save();

		return $code;
	}

	/**
	 * Reset the password if the provided password reset code matches
	 * @param string $code The reset code
	 * @return string|boolean
	 */
	public function resetPassword($code) {
		if($this->getPasswordCode() == $code) {
			$new_password = Nina_String::createRandomPassword();

			$this->setPassword(Nina_User::encode($new_password));
			$this->setPasswordCode('');
			$this->setLoginAttempts(0);
			$this->save();

			return $new_password;
		}

		return false;
	}

	/**
	* Check if this is a guest user (i.e. not logged in)
	* @return boolean
	*/
	public function isGuest() {
		return $this->isNew();
	}

	/**
	* Check if this is logged in
	* @return boolean
	*/
	public function isLoggedIn() {
		return !$this->isNew();
	}

	/**
	* Check if this user is a zero.
	* @return boolean
	*/
	public function isZeroLevel() {
		return ($this->getNumericAdminLevel() == 0);
	}

	/**
	* Check if this user is an administrator.
	* @return boolean
	*/
	public function isAdminLevel() {
		return ($this->getNumericAdminLevel() > 1);
	}

	/**
	* Check if this user is a manager or above.
	* @return boolean
	*/
	public function isManagementLevel() {
		return ($this->getNumericAdminLevel() > 3);
	}

	/**
	* Check if this user is a super or above.
	* @return boolean
	*/
	public function isSuperLevel() {
		return ($this->getNumericAdminLevel() > 4);
	}

	/**
	* Check if this user is a normal user.
	* @return boolean
	*/
	public function isUser() {
		return $this->getAdminLevel() == 'user';
	}

	/**
	* Check if this user is a manager.
	* @return boolean
	*/
	public function isAdmin() {
		return $this->getAdminLevel() == 'admin';
	}

	/**
	* Check if this user is a supervisor.
	* @return boolean
	*/
	public function isSupervisor() {
		return $this->getAdminLevel() == 'supervisor';
	}
	/**
	* Check if this user is a manager.
	* @return boolean
	*/
	public function isManager() {
		return $this->getAdminLevel() == 'manager';
	}

	/**
	* Check if this user is a super user.
	* @return boolean
	*/
	public function isSuper() {
		return $this->getAdminLevel() == 'super';
	}

	/**
	* Check if this user is a super user.
	* @return boolean
	*/
	public function isUber() {
		return $this->getAdminLevel() == 'uber';
	}


	/**
	* Get a numeric version of the admin level
	* @return string
	*/
	public function getNumericAdminLevel() {
		switch($this->getAdminLevel()) {
			case 'zero':
				return 0;
			case 'user':
				return 1;
			case 'admin':
				return 2;
			case 'supervisor':
				return 3;
			case 'manager':
				return 4;
			case 'super':
				return 5;
			case 'uber':
				return 5;
			default:
				return 1;
		}
	}

	/**
	* Get a textual version of the admin level
	* @return string
	*/
	public function getTextAdminLevel() {
		return self::textAdminLevel($this->getAdminLevel());
	}

	/**
	* Get a textual version of the admin level
	* @param string $level Admin level
	* @return string
	*/
	public static function textAdminLevel($level) {
		$levels = array('zero' =>'Zero',
					'user' =>'User',
					'admin' => 'Administrator',
					'supervisor' => 'Supervisor',
					'manager' => 'Manager',
					'super' => 'Super User',
					'uber' => 'Uber User');

		return $levels[$level];
	}

	/**
	 * Quick function to get an ordered list of users
	 * @param boolean [$active_only=false] Show only active users
	 * @return array
	 */
	public static function get($active_only = false) {
		$c = User::newCriteria();

		if($active_only)
			$c->add(User::ACTIVE, true);

		$c->addOrderBy(User::USERNAME, Nina_Orm_Criteria::ORDER_ASC);
		return User::doSelect(new User(), $c);
	}

	/**
	* Quick function to get the name of a user
	* @param integer $id User ID
	* @return string
	*/
	public static function getNameById($id) {
		if($user = User::retrieveByPk(new User(), $id))
			return $user->getUsername();
		else
			return "Unknown";
	}

	/**
	* Quick function to get the available admin levels
	* @return array
	*/
	public static function getAdminLevels() {
		$user = Nina_Registry::doGet('runtime.user');

		$levels = array('zero' => 'Zero', 'user' => 'User');

		if($user->getNumericAdminLevel() > 1)
			$levels['admin'] = 'Administrator';

		if($user->getNumericAdminLevel() > 2)
			$levels['supervisor'] = 'Supervisor';

		if($user->getNumericAdminLevel() > 3)
			$levels['manager'] = 'Manager';

		if($user->getNumericAdminLevel() > 4)
			$levels['super'] = 'Super User';

		if($user->getNumericAdminLevel() > 5)
			$levels['uber'] = 'Uber User';

		return $levels;
	}

	/**
	* Base function for special user/client select conditions
	* Ready to be overloaded by User/Client class
	* @return Nina_Orm_Criteria
	*/
	public static function getSpecialConditionsCriteria() {
		return self::newCriteria();
	}
}
